package com.checkoutcheckins.client.widgets;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.checkoutcheckins.client.data.CheckinDateDescCompare;
import com.checkoutcheckins.client.data.foursquare.Checkin;
import com.checkoutcheckins.client.data.foursquare.FoursquareCheckins;
import com.checkoutcheckins.client.data.foursquare.FoursquareUser;
import com.checkoutcheckins.client.handlers.CheckinMarkerClickHandler;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.geom.Point;
import com.google.gwt.maps.client.geom.Size;
import com.google.gwt.maps.client.overlay.Icon;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.maps.client.overlay.MarkerOptions;
import com.google.gwt.maps.client.overlay.Overlay;
import com.google.gwt.user.client.Window;

public class CheckoutCheckinsMapContainer {

	private static final LatLng US_CENTER = LatLng.newInstance(39.509, -98.434);

	private MapWidget map = null;

	private Icon mayorIcon = null;

	private Icon defaultIcon = null;

	private Icon shoutIcon = null;

	private List<String> addedVenueIds = new ArrayList<String>();

	public void createMap() {
		String mapWidth = (int) (Window.getClientWidth() - 304) + "px";
		String mapHeight = Window.getClientHeight() + "px";

		map = new MapWidget(US_CENTER, 2);
		map.setSize(mapWidth, mapHeight);
		map.setUIToDefault();
	}

	public void updateMapSize() {
		String mapWidth = (int) (Window.getClientWidth() - 304) + "px";
		String mapHeight = Window.getClientHeight() + "px";
		map.setSize(mapWidth, mapHeight);
	}

	public void setMapCenter(String geoLat, String geoLong) {
		LatLng center = LatLng.newInstance(Double.parseDouble(geoLat), Double
				.parseDouble(geoLong));

		map.setCenter(center, 12);
	}

	public MapWidget getMap() {
		if (map == null) {
			createMap();
		}
		return map;
	}

	public void addCheckinsToMap(MapWidget map,
			FoursquareCheckins foursquareCheckins) {
		addCheckinsToMap(map, foursquareCheckins, null);
	}

	public void addCheckinsToMap(MapWidget map,
			FoursquareCheckins foursquareCheckins, FoursquareUser foursquareUser) {
		
		Collections.sort(foursquareCheckins.getGeolocatedCheckins(), new CheckinDateDescCompare());

		for (Checkin checkin : foursquareCheckins.getGeolocatedCheckins()) {

			if (!addedVenueIds.contains(checkin.getVenue().getId()) && addedVenueIds.size() <= 100) {

				if (foursquareUser != null
						&& foursquareUser.getMayorVenueIds().contains(
								checkin.getVenue().getId())) {
					map.addOverlay(createMayorMarker(checkin));
				} else if (checkin.getShout() != null) {
					map.addOverlay(createShoutMarker(checkin));
				} else {
					map.addOverlay(createStandardMarker(checkin));
				}

				addedVenueIds.add(checkin.getVenue().getId());
			}
		}
	}

	// private static Marker createCategoryMarker(Checkin checkin) {
	//
	// Icon icon = Icon.newInstance(checkin.getVenue().getPrimarycategory()
	// .getIconurl());
	// icon.setShadowURL("images/markers/category_shadow.png");
	// icon.setIconSize(Size.newInstance(35, 35));
	// icon.setShadowSize(Size.newInstance(53, 35));
	// icon.setIconAnchor(Point.newInstance(18, 35));
	// icon.setInfoWindowAnchor(Point.newInstance(18, 0));
	//
	// MarkerOptions options = MarkerOptions.newInstance(icon);
	//
	// double latitude = Double.parseDouble(checkin.getVenue().getGeolat());
	// double longitude = Double.parseDouble(checkin.getVenue().getGeolong());
	//
	// Marker marker = new Marker(LatLng.newInstance(latitude, longitude),
	// options);
	//
	// GWT.log(marker.getTitle());
	//
	// return marker;
	// }

	public void addFriendCheckinsToMap(MapWidget map,
			FoursquareCheckins foursquareFriendCheckins) {

		for (Checkin checkin : foursquareFriendCheckins.getGeolocatedCheckins()) {
			map.addOverlay(createFriendMarker(checkin));
		}

	}

	private Marker createStandardMarker(Checkin checkin) {
		double latitude = Double.parseDouble(checkin.getVenue().getGeolat());
		double longitude = Double.parseDouble(checkin.getVenue().getGeolong());

		if (defaultIcon == null) {
			defaultIcon = Icon.newInstance("images/markers/defaultmarker.png");
			defaultIcon.setShadowURL("images/markers/marker_shadow.png");
			defaultIcon.setIconSize(Size.newInstance(20, 34));
			defaultIcon.setShadowSize(Size.newInstance(37, 34));
			defaultIcon.setIconAnchor(Point.newInstance(10, 34));
			defaultIcon.setInfoWindowAnchor(Point.newInstance(10, 0));
		}

		MarkerOptions options = MarkerOptions.newInstance(defaultIcon);

		Marker marker = new Marker(LatLng.newInstance(latitude, longitude),
				options);
		marker.addMarkerClickHandler(new CheckinMarkerClickHandler(marker, map,
				checkin));

		return marker;
	}

	private Marker createShoutMarker(Checkin checkin) {
		double latitude = Double.parseDouble(checkin.getVenue().getGeolat());
		double longitude = Double.parseDouble(checkin.getVenue().getGeolong());

		if (shoutIcon == null) {
			shoutIcon = Icon.newInstance("images/markers/shout.png");
			shoutIcon.setShadowURL("images/markers/marker_shadow.png");
			shoutIcon.setIconSize(Size.newInstance(20, 34));
			shoutIcon.setShadowSize(Size.newInstance(37, 34));
			shoutIcon.setIconAnchor(Point.newInstance(10, 34));
			shoutIcon.setInfoWindowAnchor(Point.newInstance(10, 0));
		}

		MarkerOptions options = MarkerOptions.newInstance(shoutIcon);

		Marker marker = new Marker(LatLng.newInstance(latitude, longitude),
				options);
		marker.addMarkerClickHandler(new CheckinMarkerClickHandler(marker, map,
				checkin));

		return marker;
	}

	private Marker createMayorMarker(Checkin checkin) {
		double latitude = Double.parseDouble(checkin.getVenue().getGeolat());
		double longitude = Double.parseDouble(checkin.getVenue().getGeolong());

		if (mayorIcon == null) {
			mayorIcon = Icon.newInstance("images/markers/crown.png");
			mayorIcon.setShadowURL("images/markers/crown_shadow.png");
			mayorIcon.setIconSize(Size.newInstance(35, 35));
			mayorIcon.setShadowSize(Size.newInstance(53, 35));
			mayorIcon.setIconAnchor(Point.newInstance(18, 35));
			mayorIcon.setInfoWindowAnchor(Point.newInstance(18, 0));
		}

		MarkerOptions options = MarkerOptions.newInstance(mayorIcon);

		Marker marker = new Marker(LatLng.newInstance(latitude, longitude),
				options);
		marker.addMarkerClickHandler(new CheckinMarkerClickHandler(marker, map,
				checkin));

		return marker;
	}

	private Overlay createFriendMarker(Checkin checkin) {
		double latitude = Double.parseDouble(checkin.getVenue().getGeolat());
		double longitude = Double.parseDouble(checkin.getVenue().getGeolong());

		Icon friendIcon = Icon.newInstance(checkin.getUser().getPhoto());
		friendIcon.setShadowURL("images/markers/friend_shadow.png");
		friendIcon.setIconSize(Size.newInstance(30, 30));
		friendIcon.setShadowSize(Size.newInstance(45, 30));
		friendIcon.setIconAnchor(Point.newInstance(15, 30));
		friendIcon.setInfoWindowAnchor(Point.newInstance(15, 0));

		MarkerOptions options = MarkerOptions.newInstance(friendIcon);

		Marker marker = new Marker(LatLng.newInstance(latitude, longitude),
				options);
		marker.addMarkerClickHandler(new CheckinMarkerClickHandler(marker, map,
				checkin));

		return marker;
	}

}
